import * as XLSX from 'xlsx';
import * as docx from 'docx-preview';
import * as pdfjsLib from 'pdfjs-dist';
import Modal from "./modal.js";
import "./index.css"

pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdf.worker.min.js';

// 调用方式: const uploadPreview = new LrFilePreview(file);

class LrFilePreview {
  constructor(file, options = {}) {

    const {
      container, // 容器id
      title, // 模态框标题
      loadingMsg, // 加载中提示
      errorMsg, // 错误提示
    } = options;

    const containerId = container ? container : 'lr-file-preview';
    const modalTitle = title ? title : '文件预览';
    const eMsg = errorMsg ? errorMsg : '预览文件错误，请重新选择。';
    const lMsg = loadingMsg ? loadingMsg : '加载中，请稍后...';

    const modal = new Modal(`
      <div id="${containerId}">
        <p class="lr-file-preview--loading">${lMsg}</p>
      </div>
    `, modalTitle);
    modal.show();

    this.preview = document.getElementById(containerId);

    if (!file) {
      this.preview.innerHTML = eMsg; // 清空预览区域
      throw new Error(eMsg);
    }

    this.options = options;
    this.globalWorkbook = null;

    this.init(file);
  }

  init(file) {
    const that = this;
    if (!file) return;

    const fileType = file.type;
    const reader = new FileReader();

    switch (fileType) {
      case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
        that.previewDocx(file, that.preview);
        break;

      case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
        reader.onload = function (e) {
          const data = new Uint8Array(e.target.result);
          that.globalWorkbook = XLSX.read(data, { type: 'array' }); // 存储到全局变量
          that.renderXLSXSheets(that.globalWorkbook, that.preview);
        };
        reader.readAsArrayBuffer(file);
        break;

      case 'application/pdf':
        that.previewPDF(file, that.preview);
        break;
      case 'text/plain':
        that.previewText(file, that.preview);
        break;
      case 'image/jpg':
      case 'image/jpeg':
      case 'image/png':
        reader.onload = function (e) {
          that.preview.innerHTML = `<img class="lr-file-preview__img" src="${e.target.result}" alt="预览图片">`;
        };
        reader.readAsDataURL(file);
        break;

      case 'text/csv':
        reader.onload = function (e) {
          const text = e.target.result;
          const rows = text.split('\n').map(row => row.split(','));
          that.preview.innerHTML = that.renderCSVTable(rows);
        };
        reader.readAsText(file);
        break;

      default:
        that.preview.innerHTML = `<p>不支持的文件格式: ${fileType}</p>`;
    }
  }

  // 文本预览
  previewText(file, previewDiv) {
    const reader = new FileReader();
    reader.onload = (e) => {
      previewDiv.innerHTML = ''; // 清空预览区域
      const pre = document.createElement('pre');
      pre.style.whiteSpace = 'pre-wrap';
      pre.style.padding = '20px';
      pre.textContent = e.target.result;
      previewDiv.appendChild(pre);
    };
    reader.readAsText(file);
  }

  // 渲染word
  previewDocx(file, previewDiv) {
    const that = this;
    docx.renderAsync(file, previewDiv)
      .then((result) => {
        console.log('Document rendered => ', result);
      })
      .catch((err) => {
        console.error('Error rendering document:', err);
      });
  }

  // 渲染pdf
  previewPDF(file, previewDiv) {
    const that = this;
    const reader = new FileReader();
    reader.onload = function (e) {
      const pdfData = e.target.result;
      pdfjsLib.getDocument({ data: pdfData }).promise.then(function (pdf) {
        that.preview.innerHTML = ''; // 清空预览区域
        for (let i = 1; i <= pdf.numPages; i++) {
          pdf.getPage(i).then(function (page) {
            const scale = 1.5;
            const viewport = page.getViewport({ scale: scale });
            const canvas = document.createElement('canvas');
            canvas.className = 'pdf-page';
            canvas.width = viewport.width;
            canvas.height = viewport.height;
            const context = canvas.getContext('2d');
            const renderContext = {
              canvasContext: context,
              viewport: viewport
            };
            page.render(renderContext);
            previewDiv.appendChild(canvas);
          });
        }
      });
    };
    reader.readAsArrayBuffer(file);
  }

  // 渲染 XLSX 文件的多 Sheet
  renderXLSXSheets(workbook, preview) {
    const that = this;
    const sheetNames = workbook.SheetNames;
    let html = `<div class="lr-file-preview__excel-tab">`;
    sheetNames.forEach((name, index) => {
      html += `<button class="lr-file-preview__excel-tab-button${index === 0 ? ' lr-file-preview__tab-active' : ''}" value="${index}">${name}</button>`;
    });
    html += `</div>`;
    preview.innerHTML = html;

    // 监听excel的tab切换
    const excelTabButtons = preview.getElementsByClassName("lr-file-preview__excel-tab-button");
    for (let i = 0; i < excelTabButtons.length; i++) {
      excelTabButtons[i].addEventListener("click", function () {
        // clear active class
        for (let j = 0; j < excelTabButtons.length; j++) {
          excelTabButtons[j].classList.remove("lr-file-preview__tab-active");
        }
        // add active class
        this.classList.add("lr-file-preview__tab-active");
        that.renderXLSXSheet();
      })
    }

    // 默认渲染第一个 Sheet
    that.renderXLSXSheet();
  }

  getColumnName(col) {
    let columnName = '';
    while (col >= 0) {
      columnName = String.fromCharCode(65 + (col % 26)) + columnName;
      col = Math.floor(col / 26) - 1;
    }
    return columnName;
  }

  // 渲染单个 XLSX Sheet
  renderXLSXSheet() {
    const that = this;
    // 清理旧表格容器
    const oldTablePanel = document.getElementsByClassName("tablePanel");
    if (oldTablePanel && oldTablePanel.length > 0) {
      that.preview.removeChild(oldTablePanel[0]);
    }
    // 创建新表格div容器
    const tablePanel = document.createElement("div");
    tablePanel.setAttribute("class", "tablePanel");
    // 修改excelselect的value
    const selectedButton = that.preview.getElementsByClassName("lr-file-preview__tab-active")[0];
    const sheetIndex = selectedButton.getAttribute("value");
    // 渲染新table
    const worksheet = this.globalWorkbook.Sheets[this.globalWorkbook.SheetNames[sheetIndex]];
    const json = XLSX.utils.sheet_to_json(worksheet, { header: 1 });

    let html = '<table class="lr-file-preview__excel-table">';
    // 添加表头（列标签：A, B, C, ...）
    html += '<thead><tr><th></th>';
    for (let col = 0; col < json[0].length + 10; col++) {
      html += `<th>${that.getColumnName(col)}</th>`;
    }
    html += '</tr></thead>';

    // 获取最长的列数
    const longestArrayLength = json.reduce((a, b) => a.length > b.length ? a : b).length;

    // 添加表格内容
    html += '<tbody>';
    for (let row = 0; row < json.length; row++) {
      html += '<tr>';
      html += `<th>${row + 1}</th>`; // 行标签（1, 2, 3, ...）
      for (let col = 0; col < json[row].length; col++) {
        html += `<td>${json[row][col] || ''}</td>`;
      }
      // 补气td
      const mapTdLen = longestArrayLength - json[row].length;
      for (let col = 0; col < mapTdLen; col++) {
        html += `<td></td>`;
      }
      for (let col = 0; col < 10; col++) {
        html += `<td></td>`;
      }
      html += '</tr>';
    }
    // 添加空白行
    for (let row = 0; row < 10; row++) {
      html += '<tr>';
      html += `<th>${json.length + row + 1}</th>`; // 行标签（1, 2, 3,...）
      for (let col = 0; col < json[0].length + 10; col++) {
        html += `<td></td>`;
      }
      html += '</tr>';
    }
    html += '</tbody></table>';
    tablePanel.innerHTML = html;
    that.preview.insertBefore(tablePanel, that.preview.firstChild);
  }

  // 渲染 PDF 文件
  renderPDF(data, preview) {
    const loadingTask = pdfjsLib.getDocument({ data });
    loadingTask.promise.then(pdf => {
      pdf.getPage(1).then(page => {
        const scale = 1.5;
        const viewport = page.getViewport({ scale });
        const canvas = document.createElement('canvas');
        const context = canvas.getContext('2d');
        canvas.height = viewport.height;
        canvas.width = viewport.width;

        preview.appendChild(canvas);

        const renderContext = {
          canvasContext: context,
          viewport: viewport,
        };
        page.render(renderContext);
      });
    }).catch(err => {
      preview.innerHTML = `<p>无法加载 PDF 文件: ${err.message}</p>`;
    });
  }

  // 渲染 CSV 表格
  renderCSVTable(data) {
    let html = '<table>';
    for (let row = 0; row < data.length; row++) {
      html += '<tr>';
      for (let col = 0; col < data[row].length; col++) {
        html += `<td>${data[row][col] || ''}</td>`;
      }
      html += '</tr>';
    }
    html += '</table>';
    return html;
  }

}

export default LrFilePreview;